#ifndef IQTPROJECTGENERATOR_H
#define IQTPROJECTGENERATOR_H

#include <QObject>
#include <QList>
#include <QSharedPointer>

#include "istatusupdater.h"

#include "generatordata.h"
#include "generatoroutputview.h"
#include "hybridpluginxmlhandler.h"
#include "defines.h"

class HybridPlugin;

struct PlatformType
{
    QString m_platformName;
    int     m_platformVersion;
    int     m_qtVersion;
};

class RcSession;

/**
  * Interface for project generators. Implementations of this interface
  * will generate projects for different platforms (symbian, maemo).
  */
class IQtProjectGenerator : public QObject
{
    Q_OBJECT

public:
    //
    // lifetime management
    //
    IQtProjectGenerator(QObject * parent = NULL);
    virtual ~IQtProjectGenerator() = 0;

    //
    // public operators
    //
signals:
    void started(GeneratorTarget target);
    void finished(int exitCode);

protected:
    //
    // common members
    //
    QMap< QString, QSharedPointer<HybridPluginPlatform> > m_selection;
    QList< QSharedPointer<HybridPlugin> > m_plugins;
    PlatformType m_platform;
    bool m_selectionDone;

public:
    /**
      * Creates and initializes a status updater object.
      *
      * The creates status updater will be wired up (signals/slots etc) using th�s
      * generator instance.
      *
      * @return a newly create instance of status updater, or NULL on failure.
      */
    virtual IStatusUpdater * createStatusUpdater(QObject * parent = NULL) = 0;

    /**
     * Returns the current platform details.
     */
    virtual const PlatformType& platform() = 0;

    /**
     * Return a list of plugins. Note that the list contains all available plugins,
     * whether compatible with the current platform or not.
     */
    virtual const QList< QSharedPointer<HybridPlugin> >& plugins();

    /**
     * Reset the platform selection for each plugin based on each plugin's
     * available versions. User should be able to override this in settings.
     */
    virtual void confirmPluginPlatform();

    /**
      * Build a widget.
      *
      * @param widgetFile - path to a widget file or directory.
      * @param rcSession the session required to build remotely, in case
      *        this qt-project-generator instance is a remote builder.
      */
    virtual void build(const QString &widgetFile,
                       RcSession     &rcSession) = 0;

    /**
      * Re-build a widget.
      *
      * @param rcSession the session required to build remotely, in case
      *        this qt-project-generator instance is a remote builder.
      */
    virtual void rebuild(RcSession   &rcSession) = 0;

    // TODO eventually, preview should go to its own class, as it is not platform
    // specific ...
    virtual void preview(const QString &widgetFile) = 0;

    virtual void closeProject() = 0;
    virtual GeneratorOutputView &outputView() const = 0;
    virtual GeneratorData &generatorData() = 0;
    virtual GeneratorPhase getCurrentPhase() const = 0;
    virtual GeneratorTarget getTarget() const = 0;
    virtual QString getStatusText() const = 0;

    /**
      * Creates a widget to paste into a dialog/window that can edit
      * settings important to the platform specific generator. Persisted
      * settings are loaded via "Settings".
      *
      * @param widgetFile the path to the currently selected widget file.
      *        Its value may be empty, in case there has been no file
      *        selections yet.
      *
      * @param parent to the widget to be created
      */
    virtual QWidget * createSettingsWidget(const QString & widgetFile,
                                           QWidget       * parent = NULL) const = 0;

    /**
      * Creates a widget to show information of plugins that are compatible
      * with the selected platform. The plugin selection can be altered
      * to enable different sets to be included in different projects.
      */
    virtual QWidget * createSettingsPluginsWidget(QWidget * parent = 0);

    /**
      * Reads settings from the widget (created by createSettingsWidget) and
      * persist them using class "Settings".
      */
    virtual void saveSettings(QWidget * settingsWidget) const = 0;

    /**
      * Reads the plugin selection from the widget and saves the selection
      * in the plugin list itself.
      */
    virtual void savePluginSettings(QWidget * settingsWidget);

    /**
      * Checks sanity of settings (perstisted by "Settings" class).
      *
      * GeneratorTarget the target to check settings for.
      */
    virtual QStringList errorsForTarget(GeneratorTarget generatorTarget) const = 0;


    /**
      * Possible outcomes of package installing action.
      */
    enum PkgInstallResult
    {
        PKGINSTALL_NOT_SUPPORTED,
        PKGINSTALL_ERROR,
        PKGINSTALL_OK
    };

    /**
      * Platform specific way of installing created package. It is an
      * optional operation.
      *
      * @param pkgFile the package file to install to a device of
      * the platform this generator represents.
      *
      * @return result of the package installing action.
      */
    virtual PkgInstallResult installPkg(const QFileInfo & pkgFile) const = 0;
};

#endif // IQTPROJECTGENERATOR_H
